package repo

import (
	"context"
	"gitlab.yoyiit.com/youyi/go-core/handler"
	"gitlab.yoyiit.com/youyi/go-core/repository"
	"gitlab.yoyiit.com/youyi/go-core/util"
)

type BusinessCertificateDBData struct {
	repository.BaseDBData
	Name                  string //名称
	Code                  string //编码
	Remark                string //说明
	Attachment            string //附件
	DueDate               string //到期日
	ImpendingReminderDays int64  //临期提醒天数
	Status                int64  //证书状态

}

type BusinessCertificateDBDataParam struct {
	BusinessCertificateDBData
	Ids []int64
}

func (*BusinessCertificateDBData) TableName() string {
	return "business_certificate"
}

func (param *BusinessCertificateDBData) getConditions() []*repository.Condition {
	return []*repository.Condition{
		repository.NewAndCondition(param),
	}
}

func (param *BusinessCertificateDBDataParam) listConditions() []*repository.Condition {
	var conditions []*repository.Condition

	if param.Ids != nil {
		conditions = append(conditions, repository.NewAndCondition("id in ?", param.Ids))
	}

	if param.Name != "" {
		conditions = append(conditions, repository.NewAndCondition("name = ?", param.Name))
	}

	if param.Code != "" {
		conditions = append(conditions, repository.NewAndCondition("code = ?", param.Code))
	}

	if param.Remark != "" {
		conditions = append(conditions, repository.NewAndCondition("remark = ?", param.Remark))
	}

	if param.Attachment != "" {
		conditions = append(conditions, repository.NewAndCondition("attachment = ?", param.Attachment))
	}

	if param.DueDate != "" {
		conditions = append(conditions, repository.NewAndCondition("due_date = ?", param.DueDate))
	}

	if param.ImpendingReminderDays != 0 {
		conditions = append(conditions, repository.NewAndCondition("impending_reminder_days = ?", param.ImpendingReminderDays))
	}
	if param.Status != 0 {
		conditions = append(conditions, repository.NewAndCondition("status = ?", param.Status))
	}

	return conditions
}

type BusinessCertificateRepo interface {
	repository.BaseCommonRepo
	Get(context.Context, *BusinessCertificateDBData) (*BusinessCertificateDBData, error)
	Count(context.Context, *BusinessCertificateDBDataParam) (int64, error)
	List(context.Context, string, int32, int32, *BusinessCertificateDBDataParam) (*[]BusinessCertificateDBData, int64, error)
	SimpleList(ctx context.Context, order string, pageNum, pageSize int32, param *BusinessCertificateDBDataParam) (*[]BusinessCertificateDBData, int64, error)
}

type businessCertificateRepo struct {
	repository.BaseRepo
}

func (r *businessCertificateRepo) Get(ctx context.Context, param *BusinessCertificateDBData) (*BusinessCertificateDBData, error) {
	data, err := r.BaseGet(ctx, repository.NewQueryBuilder().Where(param.getConditions()))
	if data == nil {
		return nil, handler.HandleError(err)
	}
	return data.(*BusinessCertificateDBData), handler.HandleError(err)
}

func (r *businessCertificateRepo) List(ctx context.Context, order string, pageNum, pageSize int32, param *BusinessCertificateDBDataParam) (*[]BusinessCertificateDBData, int64, error) {
	data, count, err := r.BaseList(ctx, repository.NewListQueryBuilder(order, pageNum, pageSize).Where(param.listConditions()))
	if data == nil {
		return nil, count, handler.HandleError(err)
	}
	return data.(*[]BusinessCertificateDBData), count, handler.HandleError(err)
}

func (r *businessCertificateRepo) SimpleList(ctx context.Context, order string, pageNum, pageSize int32, param *BusinessCertificateDBDataParam) (*[]BusinessCertificateDBData, int64, error) {
	conditions := []string{}
	params := []interface{}{}

	if param.ClinicalDocument != "" {
		conditions = append(conditions, "clinical_document = ?")
		params = append(params, param.ClinicalDocument)
	}
	if param.Name != "" {
		conditions = append(conditions, "name = ?")
		params = append(params, param.Name)
	}
	if param.Code != "" {
		conditions = append(conditions, "code = ?")
		params = append(params, param.Code)
	}
	if param.Remark != "" {
		conditions = append(conditions, "remark = ?")
		params = append(params, param.Remark)
	}
	if param.Attachment != "" {
		conditions = append(conditions, "attachment = ?")
		params = append(params, param.Attachment)
	}
	if param.DueDate != "" {
		conditions = append(conditions, "due_date = ?")
		params = append(params, param.DueDate)
	}
	if param.ImpendingReminderDays != "" {
		conditions = append(conditions, "impending_reminder_days = ?")
		params = append(params, param.ImpendingReminderDays)
	}
	if param.Status != "" {
		conditions = append(conditions, "status = ?")
		params = append(params, param.Status)
	}

	var count int64
	err := r.Db.WithContext(ctx).Model(r.Model).Where(strings.Join(conditions, " and "), params...).Count(&count).Error
	if err != nil {
		return nil, 0, handler.HandleError(err)
	}
	if count == 0 {
		return nil, 0, nil
	}
	var result []BusinessCertificateDBData
	db := r.Db.WithContext(ctx).Where(strings.Join(conditions, " and "), params...)
	if order != "" {
		db = db.Order(order)
	}
	if pageNum > 0 && pageSize > 0 {
		db = db.Offset(int((pageNum - 1) * pageSize))
		db = db.Limit(int(pageSize))
	}
	err = db.Find(&result).Error
	return &result, count, handler.HandleError(err)
}

func (r *businessCertificateRepo) Count(ctx context.Context, param *BusinessCertificateDBDataParam) (int64, error) {
	count, err := r.BaseCount(ctx, repository.NewQueryBuilder().Where(param.listConditions()))
	return count, handler.HandleError(err)
}
